package proxy;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

import net.jxta.platform.NetworkManager;
import net.jxta.socket.JxtaMulticastSocket;
import overlay.OverlayManager;

public class MulticastSniffer extends Thread {
	String ip;
	String port;
	
	NetworkManager networkManager;
	JxtaMulticastSocket mcastSocket;

	public MulticastSniffer(String group, NetworkManager networkManager, JxtaMulticastSocket mcastSocket) {
		this.ip = group.split(":")[0];
		this.port = group.split(":")[1];
		this.networkManager = networkManager;
		this.mcastSocket = mcastSocket;
		System.out.println("MulticastSniffer: Criando MulticastSniffer para ip " + this.ip + " porta " + this.port);
	}
	
	public void run () {
		// cria conexão com grupo multicast
		InetAddress ia = null;
		try {
			ia = InetAddress.getByName(this.ip);
		} catch (UnknownHostException e) {
			System.err.println("MulticastSniffer: Não foi possivel abrir socket para " + this.ip + ":" + this.port);
			ia = null;
		}
		int port = Integer.parseInt(this.port);


		if (ia != null) {
				try {
					// recebe conexões para um determinado grupo multicast
					MulticastSocket ms = new MulticastSocket(port);
					ms.joinGroup(ia);
					
//					JxtaMulticastSocket overlaySocket = new JxtaMulticastSocket(networkManager.getNetPeerGroup(),
//							OverlayManager.getSocketAdvertisement());
	
					while(true) {
					    byte[] buffer = new byte[65535];
					    DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
	
						ms.receive(dp);
						String m1 = new String (dp.getData());
						String message = m1.substring(0, m1.indexOf(0));
						System.out.println("MulticastSniffer: Mensagem recebida do grupo " + this.ip + " porta " + this.port + " conteudo = [" + message + "]");
						
						byte[] send_buffer = createPacket(message);
											
//						overlaySocket.setLoopbackMode(true); // disables loopback
						mcastSocket.setLoopbackMode(true); 
						System.out.println("MulticastSniffer: Enviando pacote para overlay com " + send_buffer.length + " bytes.");
//						overlaySocket.send(new DatagramPacket(send_buffer, send_buffer.length));
						mcastSocket.send(new DatagramPacket(send_buffer, send_buffer.length));
						System.out.println(new String(send_buffer));
					}	
				} catch (IOException e) {
					System.err.println("MulticastSniffer: Exceção recebendo pacote. " + e.getMessage());
					e.printStackTrace();
				}
		}
	}

	private byte[] createPacket(String message) {
		
		//byte[] new_packet = new byte[dp.getData().length + 25];
		//byte[] new_packet =  Arrays.copyOf(message.getBytes(), message.getBytes().length + 25);
	
		String m1 = this.ip + ":" + this.port;
		String m2 = m1 + fill_spaces(25 - m1.length());
		
		return (message + m2).getBytes();
		
/*		int i = message.getBytes().length;
		for (char c : this.ip.toCharArray()) {
			if (c == '.') 
				new_packet[i] = (byte)0;
			else
				new_packet[i] = (byte) Integer.parseInt(String.valueOf(c));
			
			i++;
		}
		new_packet[i++] = 0;
		for (char c: this.port.toCharArray()) {
			new_packet[i++] = (byte) Integer.parseInt(String.valueOf(c));
		}
		
		return new_packet;
		  */
	}

	private String fill_spaces(int num) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < num; i++) {
			sb.append(" ");
		}
		return sb.toString();
	}

}
